﻿
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;
using Swashbuckle.AspNetCore.SwaggerUI;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Swashbuckle.AspNetCore.Swagger {
    /// <summary>
    /// Swagger 扩展
    /// </summary>
    public static partial class Extensions {

        /// <summary>
        /// 配置自定义Swagger服务
        /// </summary>
        /// <param name="builder">应用程序生成器</param>
        public static IApplicationBuilder UseDefaultSwagger(this IApplicationBuilder builder) {
            builder.UseSwagger();
            builder.UseSwaggerUI(options =>
            {
                options.DocExpansion(DocExpansion.None);
                SwaggerApi.ApiInfos.ForEach(x =>
                {
                    options.SwaggerEndpoint($"/swagger/{x.UrlPrefix}/swagger.json", x.Name);
                });
                // 模型的默认扩展深度，设置为 -1 完全隐藏模型
                options.DefaultModelsExpandDepth(-1);
                // API文档仅展开标记
                options.DocExpansion(DocExpansion.List);
                // API前缀设置为空
                options.RoutePrefix ="api";
                options.DocumentTitle = "能力开放平台";
                Random rondom = new Random();

                options.InjectStylesheet("/api/swagger_custom.css?v=" + rondom.Next(1,10));
                options.InjectJavascript("https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js");
                options.InjectJavascript("/api/swagger_custom.js?v=" + rondom.Next(10, 20));

                
            });
            return builder;
        }

        /// <summary>
        /// 初始化Swagger
        /// </summary>
        /// <param name="services"></param>
        ///<param name="Configuration"></param>
        public static void InitSwagger(this IServiceCollection services, IConfiguration Configuration) {
            //添加Swagger
            services.AddSwaggerGen(options =>
            {
                SwaggerApi.ApiInfos.ForEach(x =>
                {
                    options.SwaggerDoc(x.UrlPrefix, x.OpenApiInfo);
                });
                //解决相同类名会报错的问题
                options.CustomSchemaIds(type => type.FullName);
                options.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
                //启用数据注解
                options.EnableAnnotations();
                //控制器注释
                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                if(File.Exists(xmlPath)) options.IncludeXmlComments(xmlPath, true);

                //添加JWT请求支持
                var scheme = new OpenApiSecurityScheme() {
                    Scheme = JwtBearerDefaults.AuthenticationScheme,
                    BearerFormat = "JWT",
                    In = ParameterLocation.Header,
                    //头名称
                    Name = "Authorization",
                    Type = SecuritySchemeType.ApiKey,
                    Description = "请输入带有Bearer的Token，形如 “Bearer {Token}"
                };
                options.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, scheme);
                options.OperationFilter<AddResponseHeadersFilter>();
                options.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
                options.OperationFilter<SecurityRequirementsOperationFilter>();
                options.AddSecurityRequirement(new OpenApiSecurityRequirement()
                {
                     {
                         new OpenApiSecurityScheme
                         {
                             Reference = new OpenApiReference
                             {
                                 Type = ReferenceType.SecurityScheme,
                                 Id = "Bearer"
                             }
                         },
                         new string[] {}
                     }
                 });
            });

            #region 注册JwT验证
            services.Configure<JwtSetting>(Configuration.GetSection("JWTSetting"));
            var token = Configuration.GetSection("JWTSetting").Get<JwtSetting>();
            //JWT认证
            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(token.SecretKey)),
                    ValidIssuer = token.Issuer,
                    ValidAudience = token.Audience,
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ValidateLifetime = false,

                };
            });
            #endregion
        }

    }
}
